import G6 from '@antv/g6';

import EndNode from './nodes/EndNode';
import StartNode from './nodes/StartNode';
import FlowLine from './nodes/FlowLine';
import UserTask from './nodes/UserTask';
import GateWay from './nodes/GateWay';
import {isEmpty} from '../../utils';
import Vue from 'vue';
import SupportInstance from '@/components/flow/SupportInstance.js';
import FlowModelInstance from '@/components/flow/typs/FlowModelInstance.js';
import EmptyNode from '@/components/flow/nodes/EmptyNode.js';

const h = new Vue().$createElement;

let FlowSupport;
export default FlowSupport = {
    // 解析图形属性
    resolveGraphProperties(flowModel, supportInstance) {
        //解析流程模型属性
        flowModel = JSON.parse(JSON.stringify(flowModel));
        //遍历节点
        this.traverseNode(flowModel);
        //遍历边
        this.traverseSide(flowModel);
        //样式遍历
        this.addModelStyle(flowModel, supportInstance);
        //返回流程模型
        return flowModel;
    },
    addModelStyle(flowModel, supportInstance) {
        // 历史节点
        let historyNode = supportInstance.flowPathRecord && supportInstance.flowPathRecord.historyNodeList || [];
        // 当前节点
        let currentNode = supportInstance.flowPathRecord && supportInstance.flowPathRecord.currentNodeList || [];
        // 停止节点
        let flowNodeStop = supportInstance.flowPathRecord && supportInstance.flowPathRecord.flowNodeStop || '';
        // 如果存在停止节点，那么流程将会结束
        if (flowNodeStop !== '' && historyNode.indexOf('end') === -1) {
            historyNode.push('end')
        }
        (flowModel.nodes || []).forEach(node => {
            node.history = supportInstance.history
            if (historyNode.indexOf(node.id) !== -1) {
                node.passed = true;
            } else if (currentNode.indexOf(node.id) !== -1) {
                node.active = true;
            }
            // 判断是否停止节点
            node.isNodeStop = flowNodeStop === node.id;
        });
        (flowModel.edges || []).forEach(node => {
            node.history = supportInstance.history
            if (historyNode.indexOf(node.id) !== -1) {
                node.passed = true;
            } else if (currentNode.indexOf(node.id) !== -1) {
                node.active = true;
            }
        });
    },
    traverseNode(flowModel) {
        (flowModel.nodes || []).forEach(node => {
            //设置开始节点和结束节点类型
            if (node.id === 'start') {
                node.type = 'startNode';
            }
            if (node.id === 'end') {
                node.type = 'endNode';
            }
            //设置用户任务类型
            if (node.type === 'userTask') {
            }
            //设置网关类型
            if (node.type === 'gateway') {
                if (!isEmpty((flowModel.gatewayPairs || []).find(n => n.source === node.id))) {
                    //网关开始
                    node.gatewayType = 'start';
                } else {
                    //网关结束
                    node.gatewayType = 'end';
                }
            }
        });
    },
    traverseSide(flowModel) {
        (flowModel.edges || []).forEach(edge => {
            //设置流程线类型
            edge.type = 'flowLine';
            //设置网关开始
            if (!isEmpty((flowModel.gatewayPairs || []).find(n => n.source === edge.source))) {
                //网关开始
                edge.gatewayType = 'start';
            }

            if (!isEmpty((flowModel.gatewayPairs || []).find(gp => gp.source === edge.target || gp.target === edge.target))) {
                //下一个节点是网关
                edge.endGateWay = true;
            }

            //设置网关结束
            if (!isEmpty((flowModel.gatewayPairs || []).find(n => n.target === edge.target))) {
                //网关开始
                edge.gatewayType = 'end';
            }
        });
    },

    /**
     * 创建一个图表并初始化支持实例。
     * @param {HTMLElement} container - 图表容器元素。
     * @param {Object} ctx - 上下文对象，包含图表创建所需的额外信息。
     * @returns {Object} 包含图表和支撑实例的对象。
     */
    createGraph(container, ctx) {
        let graph = undefined;
        // 创建图表并初始化支持实例
        return {
            graph: graph = this.doCreateGraph(container, ctx),
            support: new SupportInstance({graph, container, ...ctx})
        };
    },

    /**
     * 创建图表实例
     * @param {HTMLElement} container - 图表容器的DOM元素
     * @returns {Graph} 返回一个G6图表实例
     */
    doCreateGraph(container, ctx) {
        return new G6.Graph({
            container: container, // 图表容器
            width: container.offsetWidth, // 容器宽度
            height: container.offsetHeight, // 容器高度
            renderer: 'svg', // 渲染方式为SVG
            minZoom: 0.5, // 最小缩放比例
            modes: {
                default: ['zoom-canvas', 'drag-canvas'] // 默认启用的交互模式：缩放画布和拖拽画布
            },
            plugins: this.getPlugins(ctx), // 配置 Grid 插件和 Minimap 插件
            layout: {
                type: 'dagre', // 布局方式为dagre
                rankdir: 'LR', // 布局方向为从左到右
                nodesep: 30, // 节点之间的垂直间距
                ranksep: 30, // 层之间的水平间距
                controlPoints: true, // 是否显示布局中的控制点
            },
        });
    },

    getPlugins(ctx) {
        return [this.createMinimap(ctx), this.createToolBar(ctx)];
    },

    createMinimap(ctx) {
        return new G6.Minimap({
            width: '300px',
            height: '300px',
            size: [240, 180],
            container: ctx.miniMap,
            className: 'h-flow-mini-map',
        });
    },

    createToolBar(ctx) {
        return new G6.ToolBar({
            container: ctx.toolBarContainer
        });
    },

    getRank(node, ctx) {
        // 根据节点类型和节点ID动态调整层间距
        if (ctx && ctx.getModel && ctx.getModel()) {
            return this.getRankByFlowModel(node, ctx.getModel());
        }

        return this.getDefaultRank(node);
    },

    getRankByFlowModel(node, floeModel) {
        if (true) return 20
        // let res = 40;
        // let flowModelInstance = new FlowModelInstance(floeModel), nodeId = node.id;
        // if (flowModelInstance.isStart(nodeId)) {
        //   res = 30;
        // }
        // if (flowModelInstance.isEnd(nodeId)) {
        //   res = 0;
        // }
        //
        // if (flowModelInstance.isUserTask(nodeId)) {
        //   let pre = flowModelInstance.getPreNodesById(nodeId)[0];
        //   let next = flowModelInstance.getNextNodesById(nodeId)[0];
        //   if (flowModelInstance.isStartGateWay(pre.id)) {
        //     res = 30;
        //   }
        //   if (flowModelInstance.isUserTask(pre.id)) {
        //     res = 40;
        //   }
        //   if (flowModelInstance.isEndGateWay(pre.id)) {
        //     res = 20;
        //   }
        //   if (flowModelInstance.isStart(pre.id)) {
        //     res = 30;
        //   }
        //   if (flowModelInstance.isEndGateWay(next.id)) {
        //     res = 60;
        //   }
        // }
        //
        // if (flowModelInstance.isStartGateWay(node.id)) {
        //   res = 10;
        // }
        //
        // if (flowModelInstance.isEndGateWay(nodeId)) {
        //   res = 0;
        // }
        //
        // if (node.type === "empty") {
        //   res = 30;
        // }
        //
        // return res;
    },

    getDefaultRank(node) {
        if (node.type === "gateway" && node.gatewayType === 'start') {
            return 40;
        }
        if (node.type === "gateway" && node.gatewayType === 'end') {
            return 0;
        }
        if (node.id === "start") {
            return 20;
        }
        if (node.type === "userTask") {
            return 100;
        }
        if (node.id === "end") {
            return 20;
        }
        if (node.type === "empty") {
            return 60;
        }
        return 60;
    },

    /**
     * 注册图中使用的节点和边类型到 G6 图库。
     * 该函数没有参数和返回值，因为它直接操作全局注册表，影响图的全局行为。
     *
     * 注册的类型包括：
     * - 'startNode': 表示流程的开始节点；
     * - 'endNode': 表示流程的结束节点；
     * - 'userTask': 表示用户任务节点；
     * - 'gateway': 表示网关节点，用于流程的分支和合并；
     * - 'flowLine': 表示流程线，连接各个节点。
     */
    register() {
        G6.registerNode('startNode', StartNode); // 注册开始节点
        G6.registerNode('endNode', EndNode); // 注册结束节点
        G6.registerNode('userTask', UserTask); // 注册用户任务节点
        G6.registerNode('gateway', GateWay); // 注册网关节点
        G6.registerNode('empty', EmptyNode); // 注册流程线
        G6.registerEdge('flowLine', FlowLine); // 注册流程线
    },
};
